

#include <stdint.h>
#include <stdio.h>

#include "sys_settings.h"
#include "reg.h"


void SystemInit(void)
{

#if (SYS_CLK_SOURCE == 0)
	RCC_CR  |=   1<<3;  //select msi range from RCC_CR[7:4]
	RCC_CR  |=   0x7 << 4;  //configure msi clk as 8mHz
	
	RCC_CFGR  &= 	~(0x3 << 0);   //select MSI as sys_clk source;
	
	RCC_CR |=  1<<0; //enable mis clk;
	while( (RCC_CR & 0x02) ==0);   //wait until  MSI clk enabled;
#elif (SYS_CLK_SOURCE == 1) 
	
	RCC_CR |= 1 << 16;  //enable HSE on 
	//RCC_CR |= 1 << 18;  //bypass vco 
	while(   (RCC_CR &  (1<<17)) == 0 );
	
	RCC_PLLCFGR |=  0x3 << 0;   //select HSE as PLL source
	RCC_PLLCFGR &=  ~(0x7<<4);   //config  pll as source /1    8M/1 ===8M
	RCC_PLLCFGR &=  ~(0x3f<<8);
	RCC_PLLCFGR |=  10 << 8;    //config  clk as source X10   8Mx10 == 80Mhz
	RCC_PLLCFGR |=  0x1 << 24;   //enable R clock 
	RCC_PLLCFGR &=  ~(0x3 << 25);  //config clk as soruce /2   80Mhz/2==40Hz;
	
	RCC_CR  |=  0x1<< 24;   //enable pll clk source
	while(  ( RCC_CR & (0x1 <<25) ) == 0 ); //wait unitl pllclk ready

	RCC_CFGR |=  0x01 << 24;  //select sys_clk as mco output.

	RCC_CFGR |=  0x3 << 0;  //select pll as sys_clk source
	while(   ( RCC_CFGR & (0x3 <<2))  !=  (0x3 << 2) );
#endif
}


int my_fputc(int ch)
{
    while((USART1_ISR & (0x1 <<6)) == 0); 

    USART1_TDR = ch;
    return ch;
}


int my_fputs(char *s){
	for(;*s;s++)  
		my_fputc( *s);
	return 0;
}

void loop(char ch){

	while(   (USART1_ISR & (0x1 <<6)) == 0  ){
		 USART1_TDR  =   USART1_RDR & 0xff;
	}
    
}

void uart_init(){
	
	//gpio init
	RCC_AHB2ENR   |= 1<<0;     //enable gpioa clock;
	
	GPIOA_MODER   &=  ~(0x3 <<18);
	GPIOA_MODER   &=  ~(0x3 <<20);
	GPIOA_MODER   |=  (0x2 << 18)| ( 0x2 << 20) ; //config gpio 9,10 as alternate function
	
	
	GPIOA_OTYPER  &= ~( 1<<9);   //push pull
	GPIOA_OTYPER  &= ~( 1<<10);  //push pull
	GPIOA_OSPEEDR |=  (0x3 << 18) | (0x03 <<20)  ;   //very high speed;
	GPIOA_AFRH    |=  (0x7<<4) | (0x7<<8);   //gpio9,10
	
	
	
	//uart init
	//Program the Baud Rate, Word Length, Stop Bit, Parity, Prescaler value , Hardware
    //    flow control and Mode (Receiver/Transmitter) in the huart handle Init structure.
        RCC_APB2ENR   |= 1<<14;   //enable usart1 clock;
	
	USART1_CR1 = 0;	
	USART1_CR1  &= ~(0x1 << 12);   //M0  
	USART1_CR1  &= ~(0x1 << 28);   //M1    M1:M0==0  8 bit length;
	
	//USART1_CR1  |=  (1 << 15);       //oversameple  8 enabled;
	USART1_CR1  &=  ~(0x1 <<10);       //none  parity;
	USART1_CR2  &= ~(0x03 << 12);      //1 stop bit;
	USART1_CR3  &=  ~(0x3 << 8);       //disable hw flow;
	
	//USART1_BRR = 0x2b3; //115200 baud rate;  // (2*40000000/115200) ===694.44(0x2b6h)     0x2b  and  (6>>1)  ==   2b3  for oversameple 8
	USART1_BRR = 0x15b; //115200 baud rate;  // (40 000 000/115200) ===347(0x15bh)     for oversameple 16
	
	USART1_CR1  |=  (0x1 << 2 ) | (0x1 <<3) ;  //enable tx&rx;
	USART1_CR1 |= 0x1 << 0;   //enable usart;
	
}

void light_red_led(){
	
	//enable gpioe  clock
	RCC_AHB2ENR  |= 1<<4;

	//config  gpioe-7 as output 
	GPIOE_MODER = 0;
	GPIOE_MODER |=  (0x01 << 14);   //output
	GPIOE_OTYPER  &=  ~(1<<7);   //push-pull
	GPIOE_PUPDR &= ~(0x03 <<7);  //no pull up-down.
	GPIOE_ODR   &= ~(1<<7); //light  Red led
}
	
int main(){
	
    SystemInit();
    light_red_led();
    
    uart_init();
    my_fputs("hello world\r\n");
    //systick_init();
    tim6_init();
	
	
    while(1){  
	//systick_delay_ms(1000);
	tim6_delay_ms(1000);
        my_fputs("fuxxxxx luart1\r\n");
	}
	
}
